﻿using Common.Exceptions;
using Microsoft.EntityFrameworkCore;
using Wallpaper.Data.Context;
using Wallpaper.Data.IDal;
using Wallpaper.Models.DTOs.Requests.Menu;
using Wallpaper.Models.DTOs.Responses;
using Wallpaper.Models.DTOs.Responses.Permission;
using Wallpaper.Models.Entities;
using Wallpaper.Models.Options;
using Wallpaper.Services.IService;

namespace Wallpaper.Services.Service
{
    public class MenuService : IMenuService
    {

        readonly IMenuDal _menuDal;
        readonly WallpaperDbContext _dbContext;

        public MenuService(IMenuDal menuDal, WallpaperDbContext dbContext)
        {
            _menuDal = menuDal;
            _dbContext = dbContext;
        }

        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> CreateAsync(MenuRequest request)
        {
            // 2. 业务逻辑验证（如路径重复检查）
            var exists = await _menuDal.GetDbSet<Menu>()
                .AnyAsync(m => m.Path == request.Path && !m.IsDeleted);
            if (exists)
            {
                throw new BusinessException("菜单路径已存在", 400);
            }

            // 3. 映射到实体
            var menu = new Menu
            {
                Id = Guid.NewGuid().ToString(),
                Name = request.Name,
                Path = request.Path,
                Icon = request.Icon,
                Component = request.Component,
                Sort = request.Sort,
                ParentId = string.IsNullOrEmpty(request.ParentId) ? null : request.ParentId,
                IsEnabled = request.IsEnabled,
            };

            return await _menuDal.CreateEntityAsync(menu);
        }

        /// <summary>
        /// 根据adminId获取角色菜单
        /// </summary>
        /// <param name="adminId"></param>
        /// <returns></returns>
        public async Task<List<MenuSidebarResponse>> GetMenuSidebarInfoAsync(string adminId)
        {
            // 1. 查找管理员信息（包含角色）
            var admin = await _menuDal.GetDbSet<Admin>()
                .Include(a => a.Role)
                .FirstOrDefaultAsync(a => a.Id == adminId);

            if (admin == null)
            {
                return new List<MenuSidebarResponse>();
            }

            List<MenuSidebarResponse> allMenu = new List<MenuSidebarResponse>();

            // 2. 如果是超级管理员则返回所有菜单
            if (admin.IsSuperAdmin)
            {
                allMenu = await _menuDal.GetDbSet<Menu>()
                    .Include(m => m.Permissions)
                    .Where(m => !m.IsDeleted && m.IsEnabled)
                    .OrderBy(m => m.Sort)
                    .Select(m => new MenuSidebarResponse
                    {
                        Id = m.Id,
                        Title = m.Name,
                        Path = m.Path,
                        Icon = m.Icon,
                        Sort = m.Sort,
                        Type = m.Type,
                        Component = m.Component,
                        ParentId = m.ParentId,
                        CreatedTime = m.CreatedAt,
                        Permissions = m.Permissions
                            .Where(p => !p.IsDeleted)
                            .OrderBy(p => p.Sort)
                            .Select(p => new PermissionResponse
                            {
                                Code = p.Code,
                                Name = p.Name,
                                Sort = p.Sort
                            })
                            .ToList()
                    })
                    .ToListAsync();
            }
            else
            {
                // 1. 根据角色查询有权限的菜单ID
                var menuIds = await _menuDal.GetDbSet<RoleMenu>()
                    .Where(rm => rm.RoleId == admin.RoleId)
                    .Select(rm => rm.MenuId)
                    .ToListAsync();

                if (!menuIds.Any())
                {
                    return new List<MenuSidebarResponse>();
                }

                // 2. 获取菜单基本信息
                var menus = await _menuDal.GetDbSet<Menu>()
                    .Where(m => menuIds.Contains(m.Id) && !m.IsDeleted && m.IsEnabled)
                    .OrderBy(m => m.Sort)
                    .Select(m => new MenuSidebarResponse
                    {
                        Id = m.Id,
                        Title = m.Name,
                        Path = m.Path,
                        Icon = m.Icon,
                        Sort = m.Sort,
                        Type = m.Type,
                        Component = m.Component,
                        ParentId = m.ParentId,
                        CreatedTime = m.CreatedAt,
                        Permissions = new List<PermissionResponse>() // 先初始化空列表
                    })
                    .ToListAsync();

                // 3. 获取角色在每个菜单上的具体操作权限
                var rolePermissions = await (from rp in _menuDal.GetDbSet<RolePermission>()
                                             join p in _menuDal.GetDbSet<Permission>() on rp.PermissionId equals p.Id
                                             where rp.RoleId == admin.RoleId && menuIds.Contains(p.MenuId)
                                             select new { p.MenuId, Permission = p })
                                       .ToListAsync();

                // 4. 将权限数据分配到对应的菜单上
                var permissionsByMenu = rolePermissions.GroupBy(x => x.MenuId);

                foreach (var menu in menus)
                {
                    var menuPermissions = permissionsByMenu
                        .FirstOrDefault(g => g.Key == menu.Id)?
                        .Select(x => new PermissionResponse
                        {
                            Code = x.Permission.Code,
                            Name = x.Permission.Name,
                            Sort = x.Permission.Sort
                        })
                        .OrderBy(p => p.Sort)
                        .ToList();

                    if (menuPermissions != null && menuPermissions.Any())
                    {
                        menu.Permissions = menuPermissions;
                    }
                }

                allMenu = menus;
            }

            // 4. 构建树形结构
            var parentMenuList = allMenu.Where(m => string.IsNullOrEmpty(m.ParentId)).ToList();
            FindMenuChildren(parentMenuList, allMenu);

            // 5. 对顶级菜单排序
            return parentMenuList.OrderBy(m => m.Sort).ToList();
        }

        private void FindMenuChildren(List<MenuSidebarResponse> parentMenuList, List<MenuSidebarResponse> allMenu)
        {
            foreach (var parentMenu in parentMenuList)
            {
                var childMenus = allMenu.Where(m => m.ParentId == parentMenu.Id).ToList();
                if (childMenus.Any())
                {
                    // 对子菜单排序
                    parentMenu.Children = childMenus.OrderBy(m => m.Sort).ToList();
                    FindMenuChildren(parentMenu.Children, allMenu);
                }
            }
        }




        /// <summary>
        /// 更新菜单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<bool> UpdateAsync(string id, MenuRequest request)
        {
            Menu menuInfo = await _menuDal.GetDbSet<Menu>().FirstOrDefaultAsync(m => m.Id == id);
            if (menuInfo == null)
            {

                throw new BusinessException("菜单不存在或数据异常", 400);
            }
            // 2. 检查路径是否重复（排除自身）
            var pathExists = await _menuDal.GetDbSet<Menu>()
                .AnyAsync(m => m.Path == request.Path &&
                              m.Id != id &&
                              !m.IsDeleted);
            if (pathExists)
            {
                throw new BusinessException("菜单路径已存在", 400);
            }

            // 3. 检查父级菜单是否存在（如果设置了 ParentId）
            if (!string.IsNullOrEmpty(request.ParentId))
            {
                var parentExists = await _menuDal.GetDbSet<Menu>()
                    .AnyAsync(m => m.Id == request.ParentId);
                if (!parentExists)
                {
                    throw new BusinessException("指定的父级菜单不存在", 400);
                }

            }

            menuInfo.Name = request.Name;
            menuInfo.Path = request.Path;
            menuInfo.Icon = request.Icon;
            menuInfo.Component = request.Component;
            menuInfo.Sort = request.Sort;
            menuInfo.ParentId = string.IsNullOrEmpty(request.ParentId) ? null : request.ParentId;
            menuInfo.IsEnabled = request.IsEnabled;

            return await _menuDal.UpdateEntityAsync(menuInfo);

        }



        /// <summary>
        /// 获取菜单下拉
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<OptionsResponse>> GetMenuOptionsAsync()
        {
            List<OptionsResponse> options = await _menuDal.GetDbSet<Menu>().Select(m => new OptionsResponse
            {
                Value = m.Id,
                Label = m.Name
            }).ToListAsync();
            return options; ;
        }

        /// <summary>
        /// 菜单列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuSidebarResponse>> GetMenuSidebarInfoAsync()
        {
            // 直接返回所有菜单和权限，不查询管理员和角色
            var allMenu = await _menuDal.GetDbSet<Menu>()
                .Include(m => m.Permissions)  // 包含权限
                .Where(m => !m.IsDeleted && m.IsEnabled)
                .OrderBy(m => m.Sort)
                .Select(m => new MenuSidebarResponse
                {
                    Id = m.Id,
                    Title = m.Name,
                    Path = m.Path,
                    Icon = m.Icon,
                    Sort = m.Sort,
                    Type = m.Type,
                    Component = m.Component,
                    ParentId = m.ParentId,
                    Permissions = m.Permissions
                        .Where(p => !p.IsDeleted)
                        .OrderBy(p => p.Sort)
                        .Select(p => new PermissionResponse
                        {
                            Code = p.Code,
                            Name = p.Name,
                            Sort = p.Sort
                        })
                        .ToList()
                })
                .ToListAsync();
            // 构建树形结构
            var parentMenuList = allMenu.Where(m => string.IsNullOrEmpty(m.ParentId)).ToList();
            FindMenuChildren(parentMenuList, allMenu);

            // 对顶级菜单排序
            return parentMenuList.OrderBy(m => m.Sort).ToList();
        }



        /// <summary>
        /// 获取菜单下拉
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<MenuOptions>> GetAllMenusAsync()
        {
            // ✅ 查询数据库，只取必要字段
            var menuList = await _dbContext.Menus
                .Where(m => !m.IsDeleted)
                .OrderBy(m => m.Sort)
                .Select(m => new Menu
                {
                    Id = m.Id,
                    Name = m.Name,       // ✅ 与 Java title 对应
                    ParentId = m.ParentId
                })
                .ToListAsync();

            //  构建树形结构
            return BuildMenuTree(menuList);
        }

        private List<MenuOptions> BuildMenuTree(List<Menu> menus)
        {
            // 将平级列表转换成字典（key = id）
            // 将每个 Menu 对象转换为 MenuOptions 对象
            //// 假设 Menu 实体有 Id 和 Name 属性
            // MenuOptions 有 Value 和 Label 属性
            // 转换前：List<Menu>
            // [
            //   { Id: "1", Name: "系统管理", ParentId: null },
            //   { Id: "2", Name: "用户管理", ParentId: "1" }
            // ]

            // 转换后：IEnumerable<MenuOptions>  
            // [
            //   { Value: "1", Label: "系统管理", Children: [] },
            //   { Value: "2", Label: "用户管理", Children: [] }
            // ]
            var menuMap = menus
                .Select(m => new MenuOptions(m.Id, m.Name))
                //将 MenuOptions 列表转换为字典
                // key: m.Value (菜单ID)
                // value: m (整个 MenuOptions 对象)
                .ToDictionary(m => m.Value, m => m);

            // 构建树形结构
            var tree = new List<MenuOptions>();

            foreach (var menu in menus)
            {
                var node = menuMap[menu.Id];

                if (menu.ParentId == null || menu.ParentId == "0")
                {
                    tree.Add(node);
                }
                else if (menuMap.TryGetValue(menu.ParentId.ToString(), out var parent))
                {
                    parent.Children.Add(node);
                }
            }

            return tree;
        }



      
    }
}